package queue_sim

import "fmt"
import "os"
import "math"

type TestSSUI struct {
	fout * os.File 
}

type TickUITickFunction interface {
	Init (ntick int, ns int)
	ShowTick (tick int, qlen []int, load []int)
}

type TickUI struct {
	dt float64
	max_time float64
	nt	int
	ns    int

	last_time	int
	last_ss * ServiceStatus

	it_ui TickUITickFunction 
}

type TestTickUITickFunction struct {
	fout * os.File 
}

func InitTestTickUITickFunction (fname string) * TestTickUITickFunction {
	var ttf TestTickUITickFunction
	fout, err := os.Create (fname)
	ttf.fout = fout
	if (err != nil) {panic("Cannot create UI file")}
	return &ttf
}

func (tuitf * TestTickUITickFunction) Init (ntick, ns int) {
	fmt.Fprintf (tuitf.fout, "%6d%6d\n", ntick, ns)
}
func (tuitf * TestTickUITickFunction) ShowTick (tick int, qlen []int, load []int) {
	ns := len (qlen)
	fmt.Fprintf (tuitf.fout, "%6d", tick)
	for i := 0; i < ns; i ++ {
		fmt.Fprintf (tuitf.fout, "%6d%6d", qlen[i], load[i])
	}
	fmt.Fprintf (tuitf.fout, "\n")
}

func InitTestTickUI (ns int, res ServiceSimulationResult, dt float64, fout_name string) * TickUI {
	tuitf := InitTestTickUITickFunction (fout_name)
	tui := InitTickUI (ns, res, dt, tuitf)
	return tui
}

func InitTickUI (ns int, res ServiceSimulationResult, dt float64, it_ui TickUITickFunction) * TickUI {
	var ui TickUI

	ui.dt = dt
	ui.it_ui = it_ui
	ui.max_time = res.GetEndTime()
	ui.nt = int(math.Ceil (ui.max_time / ui.dt))
	ui.ns = ns

	return &ui
}

func (ui * TickUI) SimulationStart () {
	var qlen []int = make ([]int, ui.ns) 
	var load []int = make ([]int, ui.ns) 
	var ss ServiceStatus
	ss.qlen = qlen
	ss.load = load
	ss.time = 0

	ui.last_time = -1
	ui.last_ss = &ss

	ui.it_ui.Init(ui.nt, ui.ns)
}

func (ui * TickUI) ShowStatus (ass ServiceStatus, end_time float64) {
	it_start := int(math.Floor(ass.time / ui.dt))
	it_end := int(math.Floor(end_time / ui.dt))
	if (ui.last_time == -1) {
		for i := 0; i < it_start; i ++ {
			ui.it_ui.ShowTick (i, ui.last_ss.qlen, ui.last_ss.load)
		}
		ui.last_time = it_start - 1
	}
	ui.last_ss = &ass
	for i := it_start; i < it_end; i ++ {
		ui.it_ui.ShowTick (i, ass.qlen, ass.load)
	}
	if (it_start != it_end) {
		ui.last_time = it_end - 1
	}
}

func (ui * TickUI) SimulationEnd () {
	for i := ui.last_time + 1; i < ui.nt; i ++ {
		ui.it_ui.ShowTick (i, ui.last_ss.qlen, ui.last_ss.load)
	}
}


func InitTestSSUI (fname string) * TestSSUI {
	var test_ui TestSSUI
	fout, err := os.Create (fname)
	test_ui.fout = fout
	if (err != nil) {panic("Cannot create UI file")}
	return &test_ui
}

func (ui * TestSSUI) SimulationStart () {
	fmt.Fprintln (ui.fout, "Simulation Start")
}

func (ui * TestSSUI) ShowStatus (ass ServiceStatus, end_time float64) {
	fmt.Fprintf  (ui.fout, "Time: %10f --- %10f\n", ass.time, end_time)
	fmt.Fprintln (ui.fout, "	Queue Len = ", ass.qlen)
	fmt.Fprintln (ui.fout, "	Load      = ", ass.load)
}

func (ui * TestSSUI) SimulationEnd () {
	fmt.Fprintln (ui.fout, "Simulation End")
}

